﻿# ---------------------------------------------------------- #
# Active Directory Federation Services (ADFS) Configuration #
# ---------------------------------------------------------- #
param([string]$virtualMachineService, [string]$virtualMachineName)

Write-Information "Virtual machine '$virtualMachineName' ADFS '$($script.serverType)' configuration ... " -NoNewLine $true
$userName = $subscription.virtualMachines.adminUserName
$password = $subscription.virtualMachines.password
$netBiosDomain = $subscription.virtualMachines.netBiosDomain
$uri = Get-AzureWinRMUri -ServiceName $virtualMachineService -Name $virtualMachineName
$credential = New-Object System.Management.Automation.PSCredential(($netBiosDomain + "\" + $userName), (ConvertTo-SecureString $password -AsPlainText -Force))
$session = New-PSSession -ComputerName $uri[0].DnsSafeHost -Credential $credential -Port (Get-VirtualMachineInstanceEndpointPort $subscription $virtualMachineName) -UseSSL -Authentication Credssp
switch ($script.serverType)
{
	"Primary"
	{
		Invoke-Command -Session $session -ScriptBlock {
			param([string]$serviceName, [string]$userName, [string]$password, [string]$certificateName)
			$result = Add-WindowsFeature ADFS-Federation -WarningAction Ignore
            $thumbprint = (Get-Item Cert:\LocalMachine\My\* | ? {$_.FriendlyName -eq $certificateName}).Thumbprint
			$credential = New-Object System.Management.Automation.PSCredential($userName, (ConvertTo-SecureString $password -AsPlainText -Force))
			$result = Install-AdfsFarm -FederationServiceName $serviceName -ServiceAccountCredential $credential -CertificateThumbprint $thumbprint -SigningCertificateThumbprint $thumbprint -DecryptionCertificateThumbprint $thumbprint -OverwriteConfiguration
			# Set ADFS service startup type to "Automatic"
			Invoke-Expression -Command "sc.exe config adfssrv start=auto" | Out-Null
			# Verify at:
            # - https://[FQDN]/adfs/ls/idpinitiatedsignon.htm
            # - https://[FQDN]/adfs/fs/federationserverservice.asmx
            # - https://[FQDN]/federationmetadata/2007-06/federationmetadata.xml
		} -ArgumentList $script.serviceName, $script.userName, $script.password, $script.certificateName
	}
	"Secondary"
	{
		Invoke-Command -Session $session -ScriptBlock {
			param([string]$primaryName, [string]$primaryPort, [string]$userName, [string]$password, [string]$certificateName)
			$result = Add-WindowsFeature ADFS-Federation -WarningAction Ignore
            $thumbprint = (Get-Item Cert:\LocalMachine\My\* | ? {$_.FriendlyName -eq $certificateName}).Thumbprint
			$credential = New-Object System.Management.Automation.PSCredential($userName, (ConvertTo-SecureString $password -AsPlainText -Force))
			$result = Add-AdfsFarmNode -PrimaryComputerName $primaryName -PrimaryComputerPort $primaryPort -ServiceAccountCredential $credential -CertificateThumbprint $thumbprint  -OverwriteConfiguration
			# Set ADFS service startup type to "Automatic"
			Invoke-Expression -Command "sc.exe config adfssrv start=auto" | Out-Null
		} -ArgumentList $script.primaryName, $script.primaryPort, $script.userName, $script.password, $script.certificateName
	}
	"Proxy"
	{
		Invoke-Command -Session $session -ScriptBlock {
			param([string]$serviceName, [string]$userName, [string]$password, [string]$certificateName)
			Add-WindowsFeature ADFS-Proxy -WarningAction Ignore
            $thumbprint = (Get-Item Cert:\LocalMachine\My\* | ? {$_.FriendlyName -eq $certificateName}).Thumbprint
			# Setup HTTP.SYS SSL binding
			netsh http add sslcert ipport=0.0.0.0:443 certstorename=MY certhash=$thumbprint appid=`{cb1853f6-90fd-4650-94f2-fd021f256160`}
			# Setup IIS SSL binding
			New-WebBinding -Name "Default Web Site" -Protocol https -Port 443 -IPAddress "*" -HostHeader $serviceName -SslFlags 0
			# Force IIS SSL
			Set-WebConfiguration -Location "Default Web Site" -Filter 'system.webserver/security/access' -Value "Ssl" -PSPath IIS:\
			# Add ADFS Proxy
			$credential = New-Object System.Management.Automation.PSCredential($userName, (ConvertTo-SecureString $password -AsPlainText -Force))
			$result = Add-AdfsProxy -FederationServiceName $serviceName -FederationServiceTrustCredential $credential
		} -ArgumentList $script.serviceName, $script.userName, $script.password, $script.certificateName
	}
	"WebProxy"
	{
		Invoke-Command -Session $session -ScriptBlock {
			param([string]$serviceName, [string]$userName, [string]$password, [string]$certificateName)
			Install-WindowsFeature Web-Application-Proxy -IncludeManagementTools
            $thumbprint = (Get-Item Cert:\LocalMachine\My\* | ? {$_.FriendlyName -eq $certificateName}).Thumbprint
			# Add Web Application Proxy
			$result = Install-WebApplicationProxy –CertificateThumbprint $thumbprint -FederationServiceName $serviceName
		} -ArgumentList $script.serviceName, $script.userName, $script.password, $script.certificateName
	}
	"Add Relying Party"
	{
		Invoke-Command -Session $session -ScriptBlock {
			param([string]$name, [string]$identifier, [string]$wsFedEndpoint)
            if ((Get-AdfsRelyingPartyTrust -Name $name) -ne $null)
            {
                Get-AdfsRelyingPartyTrust -Name $name | Remove-AdfsRelyingPartyTrust -Confirm:$false
            }
			Add-AdfsRelyingPartyTrust -Name $name -Identifier $identifier.Split(",") -WSFedEndpoint $wsFedEndpoint `
                -ProtocolProfile WsFed-SAML `
                -IssuanceAuthorizationRules '@RuleTemplate = "AllowAllAuthzRule" => issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "true");' `
                -IssuanceTransformRules '@RuleTemplate = "LdapClaims" @RuleName = "Send LDAP Attributes as Claims" c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"] => issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn", "http://schemas.microsoft.com/ws/2008/06/identity/claims/role", "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", "http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid", "http://schemas.xmlsoap.org/claims/CommonName"), query = ";mail,userPrincipalName,tokenGroups,sAMAccountName,objectSid,displayName;{0}", param = c.Value);'
		} -ArgumentList $script.name, $script.identifier, $script.wsFedEndpoint
	}
	default
	{
		throw "ADFS Server type '$($script.serverType)' is not supported."
	}
}
Remove-PSSession $session
Write-Text "done."